package com.service.scheduling.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.service.dao.dto.MerchantCreditLineChange;
import com.service.dao.enums.CoinsEnum;
import com.service.dao.mapper.MerchantCreditLineMapper;
import com.service.dao.model.Merchant;
import com.service.dao.model.MerchantCreditLine;
import com.service.dao.model.MerchantCreditLineStatement;
import com.service.scheduling.service.MerchantCreditLineService;
import com.service.scheduling.service.MerchantCreditLineStatementService;
import com.service.scheduling.service.MerchantService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.Date;


@Service("merchantCreditLineService")
public class MerchantCreditLineServiceImpl extends ServiceImpl<MerchantCreditLineMapper, MerchantCreditLine> implements MerchantCreditLineService {


    @Autowired
    private MerchantService merchantService;
    @Autowired
    private MerchantCreditLineStatementService statementService;


    @Override
    public void updateCreditLineBalance(MerchantCreditLineChange creditLineChange) {
        updateCreditLineBalance(getCreditLine(creditLineChange.getMerchantId(), creditLineChange.getCoinsName()), creditLineChange);
    }

    public void updateCreditLineBalance(MerchantCreditLine creditLine, MerchantCreditLineChange creditLineChange) {

        creditLineChange.getStatementType().doOptStore(creditLine, creditLineChange.getChangeNum());
        BigDecimal residueNum = creditLine.getResidueNum();

        MerchantCreditLineStatement statement = MerchantCreditLineStatement.builder()
                .changeNum(creditLineChange.getChangeNum())
                .coinsId(creditLineChange.getCoinsId())
                .coinsName(creditLineChange.getCoinsName())
                .merchantId(creditLine.getMerchantId())
                .creditLineId(creditLine.getId())
                .orderId(creditLineChange.getOrderId())
                .remark(creditLineChange.getRemark())
                .residueNum(residueNum)
                .creditNum(creditLine.getCreditNum())
                .statementType(creditLineChange.getStatementType().getCode())
                .createTime(new Date())
                .build();

        statementService.save(statement);

        updateById(MerchantCreditLine.builder().creditNum(creditLine.getCreditNum())
                .residueNum(creditLine.getResidueNum()).id(creditLine.getId()).build());

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public MerchantCreditLine getCreditLine(Integer merchantId, String coinsName) {
        CoinsEnum coinsEnum = CoinsEnum.valueOf(coinsName);
        return getCreditLine(merchantId, coinsEnum);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public MerchantCreditLine getCreditLine(Integer merchantId, CoinsEnum coins) {
        MerchantCreditLine result = getOne(new QueryWrapper<MerchantCreditLine>().lambda()
                .eq(MerchantCreditLine::getMerchantId, merchantId)
                .eq(MerchantCreditLine::getCoinsName, coins.getName()));

        if (ObjectUtils.isEmpty(result)) {
            Merchant merchant = merchantService.getById(merchantId);
            if (ObjectUtils.isEmpty(merchant)) {
                return null;
            }
            result = MerchantCreditLine.builder()
                    .merchantId(merchantId)
                    .memberId(merchant.getMemberId())
                    .coinsId(coins.getCode())
                    .coinsName(coins.getName())
                    .creditNum(BigDecimal.ZERO)
                    .residueNum(BigDecimal.ZERO)
                    .createTime(new Date())
                    .build();

            save(result);
        }
        return result;
    }
}
